<?php
namespace app\install\controller;
use think\Controller;
use think\Db;
use think\Session;
class Index extends Controller
{
    /**
     * 环境检测
     * @return mixed
     */
    public function index()
    {
        $data = [];
        $data['phpversion'] = @phpversion();
        $data['os']=PHP_OS;
        $err = 0;
        if (floatval($data['phpversion']) < 5.6) {
            $data['php_ves'] = '<i class="icon icon-remove-circle"></i>' . 'php版本过低';
            $err++;
        } else {
            $data['php_ves'] = '<i class="icon icon-check-circle"></i>' . $data['phpversion'];
        }
        if (class_exists('pdo')) {
            $data['is_pdo'] = 1;
            $data['pdo'] = '<i class="icon icon-check-circle"></i>' . '已开启';
        } else {
            $data['pdo'] = '<i class="icon icon-remove-circle"></i>' . '未开启';
            $data['is_pdo'] = 0;
            $err++;
        }

        if (extension_loaded('pdo_mysql')) {
            $data['is_pdo_mysql'] = 1;
            $data['pdo_mysql'] = '<i class="icon icon-check-circle"></i>' . '已开启';
        } else {
            $data['pdo_mysql'] = '<i class="icon icon-remove-circle"></i>'. '未开启';
            $data['is_pdo_mysql'] = 0;
            $err++;
        }

        if (extension_loaded('curl')) {
            $data['is_curl'] = 1;
            $data['curl'] = '<i class="icon icon-check-circle"></i>' . '已开启';
        } else {
            $data['curl'] = '<i class="icon icon-remove-circle"></i>' . '未开启';
            $data['is_curl'] = 0;
            $err++;
        }

        if (extension_loaded('gd')) {
            $data['is_gd'] = 1;
            $data['gd'] = '<i class="icon icon-check-circle"></i>' .'已开启';
        } else {
            $data['gd'] = '<i class="icon icon-remove-circle"></i>' . '未开启';
            $data['is_gd'] = 0;
            if (function_exists('imagettftext')) {
                $data['gd'].='<br><i class="icon icon-remove-circle"></i>' . 'FreeType Support未开启';
            }
            $err++;
        }

        if (extension_loaded('mbstring')) {
            $data['is_mbstring'] = 1;
            $data['mbstring'] = '<i class="icon icon-check-circle"></i>' . '已开启';
        } else {
            $data['mbstring'] = '<i class="icon icon-remove-circle"></i>' . '未开启';
            $data['is_mbstring'] = 0;
            if (function_exists('imagettftext')) {
                $data['mbstring'].='<br><i class="icon icon-remove-circle"></i>' . 'FreeType Support未开启';
            }
            $err++;
        }

        if (function_exists('session_start')) {
            $data['is_session'] = 1;
            $data['session'] = '<i class="icon icon-check-circle"></i>' . '支持';
        } else {
            $data['session'] = '<i class="icon icon-remove-circle"></i>'  . '不支持';
            $data['is_session'] = 0;
            $err++;
        }

        $folders = [
            'apps',
            'uploads',
        ];

        $new_folders = [];
        foreach($folders as $dir){
            $Testdir = "./".$dir;
            cp_dir_create($Testdir);
            if(cp_testwrite($Testdir)){
                $new_folders[$dir]['w']=true;
            }else{
                $new_folders[$dir]['w']=false;
                $err++;
            }
            if(is_readable($Testdir)){
                $new_folders[$dir]['r']=true;
            }else{
                $new_folders[$dir]['r']=false;
                $err++;
            }
        }
        $data['folders']=$new_folders;
        return $this->fetch('index',['data'=>$data,'error'=>$err]);
    }

    /**
     * 创建数据
     * @return mixed
     */
    public function step2() {
        $id = $this->request->param('id',0,'int');
        if ($id && $id > 1) {
            $this->redirect('/sp1.html');
        }
        return $this->fetch();
    }

    /**
     * 安装完成
     * @return string
     */
    public function step3() {
        $token = $this->request->param('token');
        if ($token && mbs_strlen($token) == 8) {
            @touch(APP_PATH . "install/data/install.lock");
            return $this->fetch('step3',['data'=>Session::get('errorData')]);
        } else {
            $this->redirect('/sp1.html');
        }
    }

    /**
     * 写入文件,创建数据库
     * @return \think\response\Json
     */
    public function ajax_step() {
        if ($this->request->isAjax()) {
            $validate = new \app\common\validate\Install();
            $data = $this->request->param();
            if (!$requst = $validate->check($data)) {
                return ['error'=>1,'msg'=> $validate->getError()];
            }
            $config = [
                'type' => 'mysql',
                'hostname' => trim($data['hostname']),
                'username' => trim($data['username']),
                'password' => trim($data['password']),
                'hostport' => trim($data['hostport'])
            ];
            //链接mysql 创建数据库
            $db = Db::connect($config,true);
            $database = strtolower(trim($data['database']));
            $sql = "CREATE DATABASE IF NOT EXISTS `{$database}` DEFAULT CHARACTER SET utf8";
            $s = $db->execute($sql);
            if (!$s) {
                return ['error'=>1,'msg'=> '数据库创建失败 ^_^'];
            }
            //创建数据表
            $config['database'] = $database;
            $config['prefix'] = empty($data['prefix']) ? 'cp_' :  $data['prefix'];
            $dsn = "mysql:dbname={$config['database']};host={$config['hostname']};port={$config['hostport']};charset=utf8";
            try {
                $db = new \PDO($dsn, $config['username'], $config['password']);
            } catch (\PDOException $e) {
                return ['error'=>1,'msg'=>$e->getMessage()];
            }
            $this->_execute_sql($db, "cocolait.sql", $config['prefix']);
            //更新配置信息
            $upConfig = $this->_up_config($config);
            if ($upConfig['error']) return ['error'=>1,'msg'=>$upConfig['msg']];
            //创建管理员
            $data = [
                'username' => trim($this->request->param('uname')),
                'password' => trim($this->request->param('upwd')),
                'email' => trim($this->request->param('email'))
            ];
            $this->_create_admin_account($db,$config['prefix'],$data);
            $rand = \Cocolait\CpMsubstr::rand_string(8);
            return ['error'=>0,'msg'=>'创建数据成功,马上为您跳转...','url'=>"/sp3/{$rand}.html"];
        } else {
            return json(['error'=>1,'msg'=>'非法访问'],404);
        }
    }

    /**
     * @param $db
     * @param $file
     * @param $tablepre
     */
    protected function _execute_sql($db,$file,$tablepre){
        //读取SQL文件
        $sql = file_get_contents(APP_PATH . 'install/data/' . $file);
        $sql = str_replace("\r", "\n", $sql);
        $sql = explode(";\n", $sql);

        //替换表前缀
        $default_tablepre = "cp_";
        $sql = str_replace("{$default_tablepre}", "{$tablepre}", $sql);
        $errorData = [];

        foreach ($sql as $value) {
            $value = trim($value);
            if (empty($value)) continue;
            if( strpos($value, 'CREATE TABLE') !== false ){
                $name = preg_replace('/^CREATE TABLE `(\w+)` .*/s', '\1', $value);
                $value = str_replace("CREATE TABLE `{$name}`", "CREATE TABLE `{$name}`", $value);
                $msg  = "创建数据表{$name}";
                if (false !== $db->exec($value)) {
                    $errorData[]['msg'] = $msg . '成功!';
                } else {
                    $errorData[]['msg'] = $msg . '失败!';
                }
            }elseif ( strpos($value, 'DROP TABLE') !== false ){
                preg_match('/DROP TABLE IF EXISTS `(.*)`.*?/s', $value, $name);
                $value = str_replace("DROP TABLE IF EXISTS `{$name[1]}`", "DROP TABLE IF EXISTS `{$name[1]}`", $value);
                $msg  = "删除数据表{$name[1]}";
                if (false !== $db->exec($value)) {
                    $errorData[]['msg'] = $msg . '成功!';
                } else {
                    $errorData[]['msg'] = $msg . '失败!';
                }
            }elseif ( strpos($value, 'LOCK TABLES') !== false ){
                $name = preg_replace('/^LOCK TABLES `(\w+)` .*/s', '\1', $value);
                $value = str_replace("LOCK TABLES `{$name}", "LOCK TABLES `{$name}", $value);
                $msg  = "锁定数据表{$name}";
                if (false !== $db->exec($value)) {
                    $errorData[]['msg'] = $msg . '成功!';
                } else {
                    $errorData[]['msg'] = $msg . '失败!';
                }
            }elseif ( strpos($value, 'INSERT INTO') !== false ){
                $name = preg_replace('/^INSERT INTO `(\w+)` .*/s', '\1', $value);
                $value = str_replace("INSERT INTO `{$name}`", "INSERT INTO `{$name}`", $value);
                $msg  = "初始化表{$name}数据";
                if (false !== $db->exec($value)) {
                    $errorData[]['msg'] = $msg . '成功!';
                } else {
                    $errorData[]['msg'] = $msg . '失败!';
                }
            }else{
                $db->exec($value);
            }
        }
        Session::set('errorData',$errorData);
        return $errorData;
    }

    /**
     * 更新配置文件
     */
    private function _up_config($dbconfig) {
        if(is_array($dbconfig)){
            if (!file_exists(APP_PATH . 'database.php')) {
                @touch(APP_PATH . 'database.php');
            }
            $dbconfig['sql_explain'] = false;
            $dbconfig['auto_timestamp'] = false;
            $dbconfig['resultset_type'] = 'array';
            $dbconfig['fields_strict'] = true;
            $dbconfig['slave_no'] = '';
            $dbconfig['master_num'] = 1;
            $dbconfig['rw_separate'] = false;
            $dbconfig['deploy'] = 0;
            $dbconfig['debug'] = true;
            $dbconfig['params'] = [];
            $dbconfig['dsn'] = '';
            $dbconfig['charset'] = 'utf8';
            $str_conf = var_export($dbconfig,true);
            $conf_1 = str_replace("array (", "[", $str_conf);
            $database = "<?php return " . str_replace(")", "]", $conf_1) . ";";
            //写入应用配置文件
            if(file_put_contents(APP_PATH . 'database.php', $database)){
                return ['error'=>0,'配置文件写入成功'];
            } else {
                @unlink(APP_PATH . 'database.php');
                return ['error'=>1,'配置文件写入失败'];
            }
        }
    }

    /**
     * 创建管理员
     * @param $db
     * @param $table_prefix
     * @param $data
     */
    private function _create_admin_account($db,$table_prefix,$data) {
        $username = $data['username'];
        $password = encrypt_password($data['password']);
        $email = $data['email'];
        $sql =<<<hello
    INSERT INTO `{$table_prefix}admin`
    (uid,username,password,email) VALUES
    ('1', '{$username}', '{$password}', '{$email}');
hello;
        $db->exec($sql);
    }
}
